#ifndef _WX_FILEDIRPICKER_H_BASE_
#define _WX_FILEDIRPICKER_H_BASE_

#include "wx/defs.h"

#if wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL

#include "wx/pickerbase.h"

class wxDialog;
class wxFileDirPickerEvent;

extern const wxChar wxFilePickerWidgetLabel[];
extern const wxChar wxFilePickerWidgetNameStr[];
extern const wxChar wxFilePickerCtrlNameStr[];
extern const wxChar wxFileSelectorPromptStr[];
extern const wxChar wxDirPickerWidgetLabel[];
extern const wxChar wxDirPickerWidgetNameStr[];
extern const wxChar wxDirPickerCtrlNameStr[];
extern const wxChar wxDirSelectorPromptStr[];

class wxFileDirPickerWidgetBase {
  public:
    wxFileDirPickerWidgetBase() {  }
    virtual ~wxFileDirPickerWidgetBase() {  }

    wxString GetPath() const { return m_path; }
    virtual void SetPath( const wxString &str ) { m_path = str; }

    // returns the picker widget cast to wxControl
    virtual wxControl *AsControl() = 0;

  protected:
    virtual void UpdateDialogPath( wxDialog * ) = 0;
    virtual void UpdatePathFromDialog( wxDialog * ) = 0;

    wxString m_path;
};

#define wxFLP_OPEN                    0x0400
#define wxFLP_SAVE                    0x0800
#define wxFLP_OVERWRITE_PROMPT        0x1000
#define wxFLP_FILE_MUST_EXIST         0x2000
#define wxFLP_CHANGE_DIR              0x4000


#define wxDIRP_DIR_MUST_EXIST         0x0008
#define wxDIRP_CHANGE_DIR             0x0010

#if defined(__WXGTK26__) && !defined(__WXUNIVERSAL__)
#include "wx/gtk/filepicker.h"
#define wxFilePickerWidget      wxFileButton
#define wxDirPickerWidget       wxDirButton
#else
#include "wx/generic/filepickerg.h"
#define wxFilePickerWidget      wxGenericFileButton
#define wxDirPickerWidget       wxGenericDirButton
#endif



// ----------------------------------------------------------------------------
// wxFileDirPickerCtrlBase
// ----------------------------------------------------------------------------

class wxFileDirPickerCtrlBase : public wxPickerBase {
  public:
    wxFileDirPickerCtrlBase() : m_bIgnoreNextTextCtrlUpdate( false ) {}

  protected:
    // NB: no default values since this function will never be used
    //     directly by the user and derived classes wouldn't use them
    bool CreateBase( wxWindow *parent,
                     wxWindowID id,
                     const wxString& path,
                     const wxString &message,
                     const wxString &wildcard,
                     const wxPoint& pos,
                     const wxSize& size,
                     long style,
                     const wxValidator& validator,
                     const wxString& name );

  public:         // public API

    wxString GetPath() const;
    void SetPath( const wxString &str );

  public:        // internal functions

    void UpdatePickerFromTextCtrl();
    void UpdateTextCtrlFromPicker();

    // event handler for our picker
    void OnFileDirChange( wxFileDirPickerEvent & );

    // Returns TRUE if the current path is a valid one
    // (i.e. a valid file for a wxFilePickerWidget or a valid
    //  folder for a wxDirPickerWidget).
    virtual bool CheckPath( const wxString &str ) const = 0;

    // TRUE if any textctrl change should update the current working directory
    virtual bool IsCwdToUpdate() const = 0;

    // Returns the event type sent by this picker
    virtual wxEventType GetEventType() const = 0;

    // Returns the filtered value currently placed in the text control (if present).
    virtual wxString GetTextCtrlValue() const = 0;

  protected:
    // creates the picker control
    virtual
    wxFileDirPickerWidgetBase *CreatePicker( wxWindow *parent,
        const wxString& path,
        const wxString& message,
        const wxString& wildcard ) = 0;

  protected:

    // true if the next UpdateTextCtrl() call is to ignore
    bool m_bIgnoreNextTextCtrlUpdate;

    // m_picker object as wxFileDirPickerWidgetBase interface
    wxFileDirPickerWidgetBase *m_pickerIface;
};

#endif  // wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL


#if wxUSE_FILEPICKERCTRL

#define wxFLP_USE_TEXTCTRL            (wxPB_USE_TEXTCTRL)

#define wxFLP_DEFAULT_STYLE       (wxFLP_OPEN|wxFLP_FILE_MUST_EXIST)

class wxFilePickerCtrl : public wxFileDirPickerCtrlBase {
  public:
    wxFilePickerCtrl() {}

    wxFilePickerCtrl( wxWindow *parent,
                      wxWindowID id,
                      const wxString& path = wxEmptyString,
                      const wxString& message = wxFileSelectorPromptStr,
                      const wxString& wildcard = wxFileSelectorDefaultWildcardStr,
                      const wxPoint& pos = wxDefaultPosition,
                      const wxSize& size = wxDefaultSize,
                      long style = wxFLP_DEFAULT_STYLE,
                      const wxValidator& validator = wxDefaultValidator,
                      const wxString& name = wxFilePickerCtrlNameStr ) {
      Create( parent, id, path, message, wildcard, pos, size, style,
              validator, name );
    }

    bool Create( wxWindow *parent,
                 wxWindowID id,
                 const wxString& path = wxEmptyString,
                 const wxString& message = wxFileSelectorPromptStr,
                 const wxString& wildcard = wxFileSelectorDefaultWildcardStr,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize,
                 long style = wxFLP_DEFAULT_STYLE,
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = wxFilePickerCtrlNameStr ) {
      return wxFileDirPickerCtrlBase::CreateBase( parent, id, path,
             message, wildcard,
             pos, size, style,
             validator, name );
    }


  public:     // overrides

    // return true if the given path is valid for this control
    bool CheckPath( const wxString& path ) const;

    // return the text control value in canonical form
    wxString GetTextCtrlValue() const;

    bool IsCwdToUpdate() const
    { return HasFlag( wxFLP_CHANGE_DIR ); }

    wxEventType GetEventType() const
    { return wxEVT_COMMAND_FILEPICKER_CHANGED; }

  protected:
    wxFileDirPickerWidgetBase *CreatePicker( wxWindow *parent,
        const wxString& path,
        const wxString& message,
        const wxString& wildcard ) {
      return new wxFilePickerWidget( parent, wxID_ANY,
                                     wxFilePickerWidgetLabel,
                                     path, message, wildcard,
                                     wxDefaultPosition, wxDefaultSize,
                                     GetPickerStyle( GetWindowStyle() ) );
    }

    // extracts the style for our picker from wxFileDirPickerCtrlBase's style
    long GetPickerStyle( long style ) const {
      return ( style & ( wxFLP_OPEN | wxFLP_SAVE | wxFLP_OVERWRITE_PROMPT |
                         wxFLP_FILE_MUST_EXIST | wxFLP_CHANGE_DIR ) );
    }

  private:
    DECLARE_DYNAMIC_CLASS( wxFilePickerCtrl )
};

#endif      // wxUSE_FILEPICKERCTRL


#if wxUSE_DIRPICKERCTRL

#define wxDIRP_USE_TEXTCTRL            (wxPB_USE_TEXTCTRL)
#define wxDIRP_DEFAULT_STYLE       (wxDIRP_DIR_MUST_EXIST)

class wxDirPickerCtrl : public wxFileDirPickerCtrlBase {
  public:
    wxDirPickerCtrl() {}

    wxDirPickerCtrl( wxWindow *parent, wxWindowID id,
                     const wxString& path = wxEmptyString,
                     const wxString& message = wxDirSelectorPromptStr,
                     const wxPoint& pos = wxDefaultPosition,
                     const wxSize& size = wxDefaultSize,
                     long style = wxDIRP_DEFAULT_STYLE,
                     const wxValidator& validator = wxDefaultValidator,
                     const wxString& name = wxDirPickerCtrlNameStr ) {
      Create( parent, id, path, message, pos, size, style, validator, name );
    }

    bool Create( wxWindow *parent, wxWindowID id,
                 const wxString& path = wxEmptyString,
                 const wxString& message = wxDirSelectorPromptStr,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize,
                 long style = wxDIRP_DEFAULT_STYLE,
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = wxDirPickerCtrlNameStr ) {
      return wxFileDirPickerCtrlBase::CreateBase
             (
               parent, id, path, message, wxEmptyString,
               pos, size, style, validator, name
             );
    }


  public:     // overrides

    bool CheckPath( const wxString &path ) const;

    wxString GetTextCtrlValue() const;

    bool IsCwdToUpdate() const
    { return HasFlag( wxDIRP_CHANGE_DIR ); }

    wxEventType GetEventType() const
    { return wxEVT_COMMAND_DIRPICKER_CHANGED; }

  protected:
    wxFileDirPickerWidgetBase *CreatePicker( wxWindow *parent,
        const wxString& path,
        const wxString& message,
        const wxString& ( wildcard ) ) {
      return new wxDirPickerWidget( parent, wxID_ANY, wxDirPickerWidgetLabel,
                                    path, message,
                                    wxDefaultPosition, wxDefaultSize,
                                    GetPickerStyle( GetWindowStyle() ) );
    }
    long GetPickerStyle( long style ) const
    { return ( style & ( wxDIRP_DIR_MUST_EXIST | wxDIRP_CHANGE_DIR ) ); }

  private:
    DECLARE_DYNAMIC_CLASS( wxDirPickerCtrl )
};

#endif      // wxUSE_DIRPICKERCTRL


#if wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL

BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_COMMAND_FILEPICKER_CHANGED, 1102 )
DECLARE_EXPORTED_EVENT_TYPE( wxEVT_COMMAND_DIRPICKER_CHANGED, 1103 )
END_DECLARE_EVENT_TYPES()

class wxFileDirPickerEvent : public wxCommandEvent {
  public:
    wxFileDirPickerEvent() {}
    wxFileDirPickerEvent( wxEventType type, wxObject *generator, int id, const wxString &path )
      : wxCommandEvent( type, id ),
        m_path( path ) {
      SetEventObject( generator );
    }

    wxString GetPath() const { return m_path; }
    void SetPath( const wxString &p ) { m_path = p; }

    // default copy ctor, assignment operator and dtor are ok
    virtual wxEvent *Clone() const { return new wxFileDirPickerEvent( *this ); }

  private:
    wxString m_path;

    DECLARE_DYNAMIC_CLASS_NO_ASSIGN( wxFileDirPickerEvent )
};

// ----------------------------------------------------------------------------
// event types and macros
// ----------------------------------------------------------------------------

typedef void ( wxEvtHandler::*wxFileDirPickerEventFunction )( wxFileDirPickerEvent& );

#define wxFileDirPickerEventHandler(func) \
  (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxFileDirPickerEventFunction, &func)

#define EVT_FILEPICKER_CHANGED(id, fn) \
  wx__DECLARE_EVT1(wxEVT_COMMAND_FILEPICKER_CHANGED, id, wxFileDirPickerEventHandler(fn))
#define EVT_DIRPICKER_CHANGED(id, fn) \
  wx__DECLARE_EVT1(wxEVT_COMMAND_DIRPICKER_CHANGED, id, wxFileDirPickerEventHandler(fn))


#endif // wxUSE_FILEPICKERCTRL || wxUSE_DIRPICKERCTRL

#endif // _WX_FILEDIRPICKER_H_BASE_

